package top.infopub.mgr.util;


import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;

import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.type.JavaType;
import org.codehaus.jackson.type.TypeReference;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


/**
 * <p><b>描叙:Json处理组件</b></p>
 */
public class JsonUtil {

    private static Logger log = LoggerFactory.getLogger(JsonUtil.class);

    private static ObjectMapper objectMapper = new ObjectMapper();

    /**
     * 对象转换为Json对象
     * @param object
     * @return
     */
    public static String fromObject2Json(Object object) {
        String jsonStr = "[]";
        if (isEmpty(object)) {
            return jsonStr;
        }
        try {
            jsonStr = objectMapper.writeValueAsString(object);
        }
        catch (Exception e) {
            log.error("将对象解析成Json错误！", e);
        }
        return jsonStr;
    }

    /**
     * 将对象转换为Json格式，并设置转换时间格式
     * @param object
     *            输入对象
     * @param dateFormat
     *            输入时间格式 ‘yyyy-MM-dd’ 'yyyy-MM-dd HH:mm:ss'
     * @return
     */
    public static String fromObject2Json(Object object, String dateFormat) {
        String jsonStr = "[]";
        if (isEmpty(object)) {
            return jsonStr;
        }
        try {
            objectMapper.setDateFormat(new SimpleDateFormat(dateFormat));
            jsonStr = objectMapper.writeValueAsString(object);
        }
        catch (Exception e) {
            log.error("将对象解析成Json错误！", e);
        }
        return jsonStr;
    }

    /**
     * 将Json解析成对象
     * @param jsonstr
     * @param clazz
     * @return
     */
    public static <T> T fromJson2Object(String jsonstr, Class<T> clazz) {
        try {
            return objectMapper.readValue(jsonstr, clazz);
        }
        catch (Exception e) {
            throw new RuntimeException("Json解析对象错误！");
        }
    }

    /**
     * 把json转成HashMap对象
     * 
     * @param jsonStr
     *            json值
     * @return 返回一个HashMap对象
     */
    public static HashMap<String, Object> jsonToMap(String jsonStr) {
        HashMap<String, Object> hashMap = null;
        try {
            hashMap = objectMapper.readValue(jsonStr, new TypeReference<Map<String, Object>>() {});// 把json转成HashMap
        }
        catch (Exception e) {
            log.error("将对象解析成Json错误！", e);
        }
        return hashMap;
    }

    /**
     * 把json转成List对象
     * 
     * @param jsonStr
     *            json值
     * @return 返回一个HashMap对象
     */
    public static <T> ArrayList<T> json2List(String jsonStr, Class<T> clazz) {
        ArrayList<T> array = null;
        try {
            JavaType javaType = getCollectionType(ArrayList.class, clazz);
            array = objectMapper.readValue(jsonStr, javaType);// 把json转成ArrayList
        }
        catch (Exception e) {
            log.error("将对象解析成Json错误！", e);
        }
        return array;
    }

    /**
     * 获取泛型的Collection Type
     * 
     * @param collectionClass
     *            泛型的Collection
     * @param elementClasses
     *            元素类
     * @return JavaType Java类型
     */
    private static JavaType getCollectionType(Class<?> collectionClass, Class<?>... elementClasses) {
        return objectMapper.getTypeFactory().constructParametricType(collectionClass,
            elementClasses);
    }

    /**
     * 判断对象是否Empty(null或元素为0)<br>
     * 实用于对如下对象做判断:String Collection及其子类 Map及其子类
     * 
     * @param pObj
     *            待检查对象
     * @return boolean 返回的布尔值
     */
    @SuppressWarnings("rawtypes")
    public static boolean isEmpty(Object pObj) {
        if (pObj == null) return true;
        if (pObj.toString().equals("")) return true;
        if (pObj instanceof String) {
            if (((String)pObj).length() == 0) {
                return true;
            }
        }
        else if (pObj instanceof Collection) {
            if (((Collection)pObj).size() == 0) {
                return true;
            }
        }
        else if (pObj instanceof Map) {
            if (((Map)pObj).size() == 0) {
                return true;
            }
        }
        return false;
    }

}